package com.liantong.demo_part2.Service.Impl;

import com.liantong.demo_part2.Mapper.UpdateMapper;
import com.liantong.demo_part2.Service.UpdateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UpdateServiceImpl implements UpdateService {

    private static Map<String, Integer> AN5516 = new HashMap<>();
    private static List<Integer> AN5516_list = new ArrayList<>();
    private static Map<String, Integer> C220 = new HashMap<>();
    private static List<Integer> C220_list = new ArrayList<>();
    private static Map<String, Integer> C300 = new HashMap<>();
    private static List<Integer> C300_list = new ArrayList<>();
    private static Map<String, Integer> MA5800 = new HashMap<>();
    private static List<Integer> MA5800_list = new ArrayList<>();
    private static Map<String, Integer> MA5680 = new HashMap<>();
    private static Map<String, Integer> MA5600 = new HashMap<>();
    static {

        C220_list.add(7);
        C220_list.add(8);
        C220.put("1G", 8);
        C220.put("10G", 0);
        C220.put("board_count", 13);

        C300_list.add(1);
        C300_list.add(10);
        C300_list.add(11);
        C300.put("1G", 8);
        C300.put("10G", 8);
        C300.put("board_count", 19);

        MA5600.put("1G", 8);
        MA5600.put("10G", 0);
        MA5600.put("board_count", 8);

        MA5680.put("1G", 8);
        MA5680.put("10G", 8);
        MA5680.put("board_count", 18);

        MA5800_list.add(9);
        MA5800_list.add(10);
        MA5800.put("1G", 8);
        MA5800.put("10G", 8);
        MA5800.put("board_count", 19);

        AN5516_list.add(9);
        AN5516_list.add(10);
        AN5516.put("1G", 8);
        AN5516.put("10G", 8);
        AN5516.put("board_count", 18);

    }

    @Autowired
    private UpdateMapper updateMapper;

    @Override
    public List<List<Map<String, Object>>> plan(String rank_type, String update_type, Integer num) {
        //step1:根据传入的update_type和num,筛选出全市需要升级的PON口和条数。
        //update_type为1：直接升级，给定每个局站要升级的条数，进行全市所有局站升级num条的规划
        //update_type为2：给定全市要升级的PON口条数，筛选出前num条数据的局站和每个局站所需升级的条数
        //update_type为3：给定要升级的PON口条数，按照区域均衡法升级
        if(update_type.equals("1")){
            return update1( rank_type, num);
        }
        else if(update_type.equals("2")){
            return update2( rank_type, num);
        }
        else if (update_type.equals("3")){
            return update3( rank_type, num);
        }
        else {
            return null;
        }
    }

    /**
     * 给定全市每个局站需要升级的PON口个数，进行升级
     * @return
     */
    public List<List<Map<String, Object>>> update1(String rank_type, Integer num){
        //定义返回的数据类型
        List<List<Map<String, Object>>> list = new ArrayList<>();
        //step2.1：筛选出全市的局站信息
        List<String> all_stations1 = updateMapper.get_all_stations1();
        //step3：遍历每个局站，进行规划
        //遍历每个局站，根据rank_type字段找到要排序的num个PON口
        System.out.println("111");
        for(int i = 0; i <all_stations1.size();i++){
            //step3.1：找到和局站有关的OLT名称，设备类型
            List<Map<String, Object>> OLT_name_list = updateMapper.find_olt_name_list(all_stations1.get(i));
            //step3.2:找到该局站下需要升级的PON口
            List<Map<String,Object>> PON_remain_to_update;
            if(rank_type.equals("zhijie")){
                System.out.println(all_stations1.get(i));
                PON_remain_to_update = updateMapper.find_pon_to_update_zhijie(num,all_stations1.get(i));
            }
            else if(rank_type.equals("AHP")){
                PON_remain_to_update = updateMapper.find_pon_to_update_AHP(num,all_stations1.get(i));
            }
            else if (rank_type.equals("TOPSIS")){
                PON_remain_to_update = updateMapper.find_pon_to_update_TOPSIS(num,all_stations1.get(i));
            }
            else {
                return null;
            }
            //step3.3找到该局站每个OLT有关的数据进行统计，得到每台OLT的名称、PON板数组、PON口数组
            List<Map<String, Object>> olt_state = cal_pon_board_and_port(OLT_name_list, all_stations1.get(i));
            //step3.4进行升级，结果加入result中。
            System.out.println("22222");
            list.add(update_pon_board_and_port(all_stations1.get(i), PON_remain_to_update, olt_state));
            update_pon_board_and_port(all_stations1.get(i), PON_remain_to_update, olt_state);
            //todo:二次升级策略应该放在此处进行
            List<Map<String,Object>> PON_remain_to_update_erci =  erci_update(olt_state,PON_remain_to_update,rank_type,all_stations1.get(i));
            PON_remain_to_update.addAll(PON_remain_to_update_erci);
            list.add(PON_remain_to_update);

        }
        return list;
    }


    /**
     * 统计每个OLT的端口使用情况
     */
    public List<Map<String, Object>> cal_pon_board_and_port(List<Map<String, Object>> OLT_name_list, String station) {
        List<Map<String, Object>> result = new ArrayList<>();
        //1.遍历OLT_name_list,根据每个olt_pon_name找到相关的PON板、PON口数据集合
        for (int i = 0; i < OLT_name_list.size(); i++) {
            Map<String, Object> temp_map = new HashMap<>();
            //传入olt_name,查出1、有关的PON口数据集合；2、以PON板为单位的数据集合
            List<Map<String, Object>> olt_pon_port_data = updateMapper.select_pon_port_data_by_olt_name(OLT_name_list.get(i).get("olt_pon_name").toString());
            List<Map<String, Object>> olt_pon_data = updateMapper.select_pon_data_by_olt_name(OLT_name_list.get(i).get("olt_pon_name").toString());
            //根据查询的设备类型，设置业务板槽数组长度值。
            int[] olt_board;
            String model = olt_pon_port_data.get(0).get("model").toString();
            if (model.contains("AN5516"))
                olt_board = new int[AN5516.get("board_count")];
            else if (model.contains("C220"))
                olt_board = new int[C220.get("board_count")];
            else if (model.contains("C300"))
                olt_board = new int[C300.get("board_count")];
            else if (model.contains("MA5800"))
                olt_board = new int[MA5800.get("board_count")];
            else if (model.contains("MA5680"))
                olt_board = new int[MA5680.get("board_count")];
            else if (model.contains("MA5600"))
                olt_board = new int[MA5600.get("board_count")];
            else {
                //为了防止程序检测的可能没出现初始化的情况，实际上不包含这种情况。
                olt_board = new int[24];
            }
            //PON板辅助数组初始化全为0
            for (int index = 0; index < olt_board.length; index++) {
                olt_board[index] = 0;
            }
            //定义该OLT的端口数组
            int[][] olt_port = new int[olt_board.length][];
            //初始化PON_port二维辅助数组
            for (int temp1 = 0; temp1 < olt_port.length; temp1++) {
                int[] list = new int[8];
                for (int temp2 = 0; temp2 < list.length; temp2++) {
                    list[temp2] = 0;
                }
                olt_port[temp1] = list;
            }
            //该OLTPON板、端口状态更新
            //此处应遵循规范如下：
            //1.所有型号的OLTPON板实际逻辑端口都从下标1开始
            //2.所有需要跳过的逻辑端口为真实数值
            //3.华为设备的PON口实际逻辑端口从0开始，其余的从1开始
            for (int j = 0; j < olt_board.length; j++) {
                //默认数据库板下标从1开始，连续使用pon_board_number个PON板如1：17直接记为业务板槽
                //1.遍历olt_pon_data_unique，如果出现PON板序号和j+1相等的情况，olt_port[j]置1或2表示原先就已经使用的1GPON板和１０GPON板；否则置0表示未使用
                //2.同时给port数组进行初始化。
                for (Map mp : olt_pon_data) {
                    if (mp.get("pon_board_number").toString().equals(String.valueOf(j + 1))) {
                        if (mp.get("bandwidth").toString().contains("10G")) {
                            olt_board[j] = 2;
                        } else if (mp.get("bandwidth").toString().contains("G")) {
                            olt_board[j] = 1;
                        } else {
                            //非1G和10G的情况，可能会出现，暂时没想好怎么处理。
                            olt_board[j] = -1;
                        }
                    }
                }
                //给当前PON板的端口辅助数组赋值
                //华为、中心的数据pon口起始下标不一样，需要在这里做判定和调整
                if (olt_pon_port_data.size() != 0 & (model.equals("MA5680T")||model.equals("MA5600T")||model.equals("MA5800-X17"))) {
                    for (Map mp : olt_pon_port_data) {
                        if (mp.get("pon_board_number").toString().equals(String.valueOf(j + 1)))
//                            System.out.println("board: "+mp.get("pon_board_number").toString() +"   port:"+mp.get("pon_port_number").toString());
                            olt_port[j][Integer.parseInt(mp.get("pon_port_number").toString())] = 1;
                    }
                } else {
                    for (Map mp : olt_pon_port_data) {
                        if (mp.get("pon_board_number").toString().equals(String.valueOf(j + 1)))
//                            System.out.println("board: "+mp.get("pon_board_number").toString() +"   port:"+mp.get("pon_port_number").toString());
                            olt_port[j][Integer.parseInt(mp.get("pon_port_number").toString()) - 1] = 1;
                    }
                }

            }
            //新增对每个OLT数组跳过的PON板号的数值更新
            if (model.contains("AN5516")){
                for(int index = 0; index <AN5516_list.size();index++){
                    olt_board[AN5516_list.get(index)-1] = -9;
                }
            }
            else if (model.contains("C220")) {
                for (int index = 0; index < C220_list.size(); index++) {
                    olt_board[C220_list.get(index) - 1] = -9;
                }
            }
            else if (model.contains("C300")){
                for (int index = 0; index < C300_list.size(); index++) {
                    olt_board[C300_list.get(index) - 1] = -9;
                }
            }
            else if (model.contains("MA5800")){
                for (int index = 0; index < MA5800_list.size(); index++) {
                    olt_board[MA5800_list.get(index) - 1] = -9;
                }
            }
            temp_map.put("olt_pon_name", olt_pon_data.get(0).get("olt_pon_name").toString());
            temp_map.put("array_board", olt_board);
            temp_map.put("array_port", olt_port);
            result.add(temp_map);
        }
        return result;
    }


    /**
     * 规划升级的具体方法：需要传递该局站的每个OLT的PON板和端口数组，以及待升级的PON口列表
     * @return
     */
    //若要新建OLT，则新建华为5800型号，默认为19业务槽位（不用9和10）、8个10GPON口。
    public List<Map<String, Object>> update_pon_board_and_port(String station, List<Map<String, Object>> PON_remain_to_update, List<Map<String, Object>> olt_state) {
        int new_olt_index = 1;
        //1.打分结果记录中加入新字段，初始化。
        for (Map score : PON_remain_to_update) {
            score.put("if_necessary", "");//是否必须扩容
            score.put("operate_type", "");//操作类型
            score.put("target_OLT", "");//目标OLT名称
            score.put("target_port", "");//目标端口
        }
        //根据打分结果表的待升级PON口顺序，从olt_state列表中找到空闲PON口，空闲PON板，或新建OLT来升级。
        //2.遍历每条需要扩容的打分记录，进行局站内打分结果的扩容规划
        for (Map score : PON_remain_to_update) {
            boolean this_record_planed = false;
            //2.2优先同一OLT进行割接扩容，割接到其他空闲10GPON板的PON口下
            out_self1:
            for (Map mp : olt_state) {
                if (mp.get("olt_pon_name").toString().equals(score.get("olt_pon_name").toString())) {
                    //2.2.1得到当前OLT的PON板，PON口使用情况约定如下：
                    //PON板：原本未使用的为0；已使用的1GPON板为1；已使用的10GPON板为2；扩容新增（必须扩容）的10GPON板为3;扩容新增（非必须扩容）的10GPON板为4;
                    //PON口：原本未使用的为0；已使用的为1；扩容新增使用的（必须扩容）为2；扩容新增使用的（非必须扩容）为3；原有必须扩容撤下的PON口为-2；原有必须扩容撤下的PON口为-3
                    int[] board_temp = (int[]) mp.get("array_board");
                    int[][] port_temp = (int[][]) mp.get("array_port");
                    //2.2.2找空闲10GPON口直接割接
                    for (int i = 0; i < board_temp.length; i++) {
                        //2.2.2.1找10GPON板
                        if (board_temp[i] == 2 || board_temp[i] == 3 || board_temp[i] == 4) {
                            for (int j = 0; j < port_temp[i].length; j++) {
                                //2.2.2.1.1找空闲PON口；由于撤下的原有使用PON口都是非10G的，所以不用考虑
                                if (port_temp[i][j] == 0) {
                                    //直接升级，迁入的PON口标号记为2
                                    port_temp[i][j] = 2;
                                    //如果中兴设备，PON口下标从1开始；其余从0开始
                                    String[] pon_port = score.get("pon_port").toString().split("--");
                                    if (mp.get("olt_pon_name").toString().contains("_HW_")) {
                                        port_temp[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1])] = -2;
                                        score.put("target_port", String.valueOf(i + 1) + "--" + String.valueOf(j));//目标端口

                                    } else {
                                        port_temp[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1]) - 1] = -2;
                                        score.put("target_port", String.valueOf(i + 1) + "--" + String.valueOf(j + 1));//目标端口
                                    }
                                    //更新打分结果中的字段数据
                                    if(board_temp[i] == 2)
                                        score.put("operate_type", "原有的OLT上找到空闲端口进行扩容");//操作类型
                                    else
                                        score.put("operate_type", "原有的OLT上新建PON板进行扩容");//操作类型
                                    score.put("target_OLT", mp.get("olt_pon_name").toString());//目标OLT名称
                                    this_record_planed = true;
                                    mp.put("array_port", port_temp);
                                    break out_self1;
                                }
                            }
                        }
                    }
                    //2.2.3若直接找空闲PON口割接不成功，同OLT找空闲槽位新建PON板割接
                    for (int i = 0; i < board_temp.length; i++) {
                        //2.2.3.1找空闲PON板
                        if (board_temp[i] == 0) {
                            board_temp[i] = 4;
                            port_temp[i][0] = 2;
                            //如果华为设备，PON口下标从0开始；其余从1开始
                            String[] pon_port = score.get("pon_port").toString().split("--");
                            if (mp.get("olt_pon_name").toString().contains("_HW_")) {
                                score.put("target_port", String.valueOf(i + 1) + "--" + String.valueOf(0));//目标端口
                                port_temp[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1])] = -2;
                            } else {
                                score.put("target_port", String.valueOf(i + 1) + "--" + String.valueOf(1));//目标端口
                                port_temp[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1]) - 1] = -2;
                            }
                            //更新打分结果中的字段数据
                            score.put("operate_type", "原有的OLT上新建PON板进行扩容");//操作类型
                            score.put("target_OLT", mp.get("olt_pon_name").toString());//目标OLT名称
                            this_record_planed = true;
                            mp.put("array_port", port_temp);
                            mp.put("array_board", board_temp);
                            break out_self1;

                        }
                    }
                }
            }
            //2.3由于是非同一OLT，需要获取olt_state中和打分结果匹配的OLTPON板、PON口使用情况的数组，做旧PON口撤除的数据更新
            //由于打分结果表和pon表目前不是基于同一时间的数据，OLT可能不匹配，后续的逻辑需要加入非空判定。
            int[] board_score_OLT = null;
            int[][] port_score_OLT = null;
            int OLT_index = 0;
            find_score:
            for (Map mp : olt_state) {
                if (mp.get("olt_pon_name").toString().equals(score.get("olt_pon_name").toString())) {
                    board_score_OLT = (int[]) mp.get("array_board");
                    port_score_OLT = (int[][]) mp.get("array_port");
                    OLT_index = olt_state.indexOf(mp);
                    break find_score;
                }
            }
            //2.4如果同OLT割接不成功，找同局其他设备的空闲PON口进行割接
            if (!this_record_planed) {
                out:
                for (Map mp : olt_state) {
                    //2.4.1获取当前OLT的PON板、PON口使用情况
                    int[] board_temp = (int[]) mp.get("array_board");
                    int[][] port_temp = (int[][]) mp.get("array_port");
                    //2.4.2找空闲10GPON口直接割接
                    for (int i = 0; i < board_temp.length; i++) {
                        //2.4.2.1找10GPON板
                        if (board_temp[i] == 2 || board_temp[i] == 3 || board_temp[i] == 4) {
                            for (int j = 0; j < port_temp[i].length; j++) {
                                //如果找到了空闲端口，则进行端口直接割接,并记录割接结果
                                if (port_temp[i][j] == 0) {
                                    port_temp[i][j] = 2;
                                    //如果华为设备，PON口下标从0开始；其余从1开始
                                    String[] pon_port = score.get("pon_port").toString().split("--");
                                    if (mp.get("olt_pon_name").toString().contains("_HW_")) {
                                        score.put("target_port", String.valueOf(i + 1) + "--" + String.valueOf(j));//目标端口
                                        if (port_score_OLT != null)
                                            port_score_OLT[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1])] = -2;
                                    } else {
                                        score.put("target_port", String.valueOf(i + 1) + "--" + String.valueOf(j+1));//目标端口
                                        if (port_score_OLT != null)
                                            port_score_OLT[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1]) - 1] = -2;
                                    }
                                    //判断是否是新建OLT扩容
                                    if (mp.get("olt_pon_name").toString().contains("new_olt")) {
                                        score.put("operate_type", "新建OLT进行扩容");//操作类型
                                    } else if (board_temp[i] == 2) {
                                        score.put("operate_type", "原有的OLT上找到空闲端口进行扩容");//操作类型
                                    } else {
                                        score.put("operate_type", "原有的OLT上新建PON板进行扩容");//操作类型
                                    }
                                    score.put("target_OLT", mp.get("olt_pon_name").toString());//目标OLT名称
                                    this_record_planed = true;
                                    //更新撤下PON的OLT和迁移PON的OLT的PON板和PON口数组数据
                                    mp.put("array_port", port_temp);
                                    //如果非空，更新撤下PON口的OLTPON口状态数组。
                                    if (port_score_OLT != null) {
                                        Map<String, Object> mp2 = olt_state.get(OLT_index);
                                        mp2.put("array_port", port_score_OLT);
                                    }
                                    break out;
                                }
                            }
                        }
                    }
                }
            }
            //2.5如果找不到空闲PON口，找空闲PON板
            if (!this_record_planed) {
                out2:
                for (Map mp : olt_state) {
                    //2.5.1获取当前OLT的PON板、PON口使用情况
                    int[] board_temp = (int[]) mp.get("array_board");
                    int[][] port_temp = (int[][]) mp.get("array_port");
                    //2.5.2找空闲10GPON口直接割接
                    for (int i = 0; i < board_temp.length; i++) {
                        //2.5.2.1找10GPON板
                        if (board_temp[i] == 0) {
                            board_temp[i] = 4;
                            port_temp[i][0] = 2;
                            //如果华为设备，PON口下标从0开始；其余从1开始
                            String[] pon_port = score.get("pon_port").toString().split("--");
                            if (mp.get("olt_pon_name").toString().contains("_HW_")) {
                                score.put("target_port", String.valueOf(i + 1) + "--" + String.valueOf(0));//目标端口
                                if (port_score_OLT != null)
                                    port_score_OLT[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1])] = -2;
                            } else {
                                score.put("target_port", String.valueOf(i + 1) + "--" + String.valueOf(1));//目标端口
                                if (port_score_OLT != null)
                                    port_score_OLT[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1])-1] = -2;
                            }
                            //更新打分结果中的字段数据
                            if (mp.get("olt_pon_name").toString().contains("new_olt")) {
                                score.put("operate_type", "新建OLT进行扩容");//操作类型
                            } else {
                                score.put("operate_type", "原有的OLT上新建PON板进行扩容");//操作类型
                            }
                            score.put("target_OLT", mp.get("olt_pon_name").toString());//目标OLT名称
                            //更新撤下PON的OLT和迁移PON的OLT的PON板和PON口数组数据
                            this_record_planed = true;
                            mp.put("array_port", port_temp);
                            mp.put("array_board", board_temp);
                            //如果非空，更新撤下PON口的OLTPON口状态数组。
                            if (port_score_OLT != null) {
                                Map<String, Object> mp2 = olt_state.get(OLT_index);
                                mp2.put("array_port", port_score_OLT);
                            }
                            break out2;
                        }
                    }
                }
            }
            //2.6找不到空闲PON板，扩建OLT。
            out3:
            if (!this_record_planed) {
                //初始化
                Map<String, Object> new_olt_state = new HashMap<>();
                new_olt_state.put("olt_pon_name", "new_olt_HW_" + new_olt_index);
                new_olt_index++;
                //定义新OLT的辅助数组,并初始化
                int[] olt_board;
                olt_board = new int[MA5800.get("board_count")];
                int[][] olt_port = new int[olt_board.length][8];
                for (int i = 0; i < olt_board.length; i++) {
                    olt_board[i] = 0;
                    for (int temp = 0; temp < 8; temp++)
                        olt_port[i][temp] = 0;
                }
                for (int index = 0; index < MA5800_list.size(); index++) {
                    olt_board[MA5800_list.get(index) - 1] = -9;
                }
                new_olt_state.put("station", station);
                //使用空闲端口进行扩容，必须扩容设为2，非必须扩容设为3
                //恢复原本端口的使用状态，需不许扩容恢复的为-2；非必须扩容的回复为-3

                olt_board[0] = 4;
                olt_port[0][0] = 2;
                //华为设备，设置规划结果的目标端口。
                String[] pon_port = score.get("pon_port").toString().split("--");
                if (port_score_OLT != null)
                    port_score_OLT[Integer.parseInt(pon_port[0]) - 1][Integer.parseInt(pon_port[1])] = -2;

                //使用该新增的olt端口
                new_olt_state.put("array_port", olt_port);
                new_olt_state.put("array_board", olt_board);
                //olt_state状态列表新增该OLT。
                olt_state.add(new_olt_state);
                this_record_planed = true;
                score.put("target_port", String.valueOf(1) + "--" + String.valueOf(0));//目标端口
                score.put("operate_type", "新建OLT进行扩容");//操作类型
                score.put("target_OLT", new_olt_state.get("olt_pon_name").toString());//目标OLT名称
                //如果非空，更新撤下PON口的OLTPON口状态数组。
                if (port_score_OLT != null) {
                    Map<String, Object> mp2 = olt_state.get(OLT_index);
                    mp2.put("array_port", port_score_OLT);
                }
                break out3;
            }
            //打分结果表基于2019年12月的数据，而查询结果目前根据2018年9月数据。
        }
        //把结果转成合适的返回数据。从olt_state里面寻找数据和封装。
        return PON_remain_to_update;
    }




    /**
     * 给定全市总共需要升级的PON口个数，进行升级
     * @return
     */
    public List<List<Map<String, Object>>> update2(String rank_type, Integer num){
        //定义返回的数据类型
        List<List<Map<String, Object>>> list = new ArrayList<>();
        //step2.1：筛选出num条带规划数据的局站信息及每个局站需要规划的条数
        List<Map<String, Object>> all_stations_and_count = new ArrayList<>();
        if(rank_type.equals("zhijie")){
            all_stations_and_count = updateMapper.find_stations_and_nums_zhijie(num);
        }
        else if(rank_type.equals("AHP")){
            all_stations_and_count = updateMapper.find_stations_and_nums_AHP(num);
        }
        else if (rank_type.equals("TOPSIS")){
            all_stations_and_count = updateMapper.find_stations_and_nums_TOPSIS(num);
        }
        System.out.println(all_stations_and_count);
        //step3：遍历每个局站，进行规划
        //遍历每个局站，根据rank_type字段找到要排序的num个PON口
        for(int i = 0; i <all_stations_and_count.size();i++){
            //step3.1：找到和局站有关的OLT名称，设备类型
            List<Map<String, Object>> OLT_name_list = updateMapper.find_olt_name_list(all_stations_and_count.get(i).get("station").toString());
            System.out.println(OLT_name_list);
            //step3.2:找到该局站下需要升级的PON口
            List<Map<String,Object>> PON_remain_to_update;
            if(rank_type.equals("zhijie")){
                PON_remain_to_update = updateMapper.find_pon_to_update_zhijie(Integer.parseInt(all_stations_and_count.get(i).get("num").toString()),all_stations_and_count.get(i).get("station").toString());
                System.out.println(all_stations_and_count.get(i));
                System.out.println(PON_remain_to_update);
            }
            else if(rank_type.equals("AHP")){
                PON_remain_to_update = updateMapper.find_pon_to_update_AHP(Integer.parseInt(all_stations_and_count.get(i).get("num").toString()),all_stations_and_count.get(i).get("station").toString());
            }
            else if (rank_type.equals("TOPSIS")){
                PON_remain_to_update = updateMapper.find_pon_to_update_TOPSIS(Integer.parseInt(all_stations_and_count.get(i).get("num").toString()),all_stations_and_count.get(i).get("station").toString());
            }
            else {
                return null;
            }
            //step3.3找到该局站每个OLT有关的数据进行统计，得到每台OLT的名称、PON板数组、PON口数组
            List<Map<String, Object>> olt_state = cal_pon_board_and_port(OLT_name_list, all_stations_and_count.get(i).get("station").toString());
            //step3.4进行升级，结果加入result中。
            System.out.println("22222");
            update_pon_board_and_port(all_stations_and_count.get(i).get("station").toString(), PON_remain_to_update, olt_state);
            //todo:二次升级策略应该放在此处进行
            List<Map<String,Object>> PON_remain_to_update_erci =  erci_update(olt_state,PON_remain_to_update,rank_type,all_stations_and_count.get(i).get("station").toString());
            PON_remain_to_update.addAll(PON_remain_to_update_erci);
            list.add(PON_remain_to_update);
        }
        return list;
    }



    /**
     * 给定全市总共需要升级的PON口个数，进行升级
     * @return
     */
    public List<List<Map<String, Object>>> update3(String rank_type, Integer num){
        int num1,num2;
        num1 =new Double(num*0.8).intValue();
        num2 =new Double(num*0.2).intValue();
        //定义返回的数据类型
        List<List<Map<String, Object>>> list = new ArrayList<>();
        //step2.1：筛选出num1条带规划数据的局站信息及每个局站需要规划的条数
        List<Map<String, Object>> all_stations_and_count = new ArrayList<>();
        List<String> all_stations = updateMapper.get_all_stations1();
        System.out.println("all_stations: "+all_stations.size());
        if(rank_type.equals("zhijie")){
            all_stations_and_count = updateMapper.find_stations_and_nums_zhijie(num1);
        }
        else if(rank_type.equals("AHP")){
            all_stations_and_count = updateMapper.find_stations_and_nums_AHP(num1);
        }
        else if (rank_type.equals("TOPSIS")){
            all_stations_and_count = updateMapper.find_stations_and_nums_TOPSIS(num1);
        }
        List<String> station_in_num1 = new ArrayList<>();
        for(Map<String,Object> mp:all_stations_and_count){
            station_in_num1.add(mp.get("station").toString());
        }
        System.out.println("station_in_num1: "+station_in_num1.size());
        all_stations.removeAll(station_in_num1);
        System.out.println("all_stations2: "+all_stations.size());
        List<Map<String, Object>> all_stations_count2 = new ArrayList<>();
        if(new Double(Math.ceil(num2/all_stations.size())).intValue()==0){
            int count = 0;
            int num_add = new Double(Math.ceil(num2/all_stations.size())).intValue();
            for(String s:all_stations){
                Map<String,Object> mp = new HashMap<>();
                if(num_add*all_stations.size()+count<num2){

                    mp.put("station",s);
                    mp.put("num",num_add+1);
                    count++;
                }
                else {

                    mp.put("station",s);
                    mp.put("num",num_add+1);
                }
                all_stations_count2.add(mp);
            }
            all_stations_and_count.addAll(all_stations_count2);
        }
        else {
            if(rank_type.equals("zhijie")){
                all_stations_and_count = updateMapper.find_stations_and_nums_zhijie(num);
            }
            else if(rank_type.equals("AHP")){
                all_stations_and_count = updateMapper.find_stations_and_nums_AHP(num);
            }
            else if (rank_type.equals("TOPSIS")){
                all_stations_and_count = updateMapper.find_stations_and_nums_TOPSIS(num);
            }
        }
        System.out.println("all_stations_and_count:"+all_stations_and_count.size());
        //step3：遍历每个局站，进行规划
        //遍历每个局站，根据rank_type字段找到要排序的num个PON口
        for(int i = 0; i <all_stations_and_count.size();i++){
            //step3.1：找到和局站有关的OLT名称，设备类型
            System.out.println(all_stations_and_count.get(i));
            System.out.println(all_stations_and_count.get(i).get("station").toString());
            List<Map<String, Object>> OLT_name_list = updateMapper.find_olt_name_list(all_stations_and_count.get(i).get("station").toString());
            System.out.println(OLT_name_list);
            //step3.2:找到该局站下需要升级的PON口
            List<Map<String,Object>> PON_remain_to_update;
            if(rank_type.equals("zhijie")){
                PON_remain_to_update = updateMapper.find_pon_to_update_zhijie(Integer.parseInt(all_stations_and_count.get(i).get("num").toString()),all_stations_and_count.get(i).get("station").toString());
                System.out.println(all_stations_and_count.get(i));
                System.out.println(PON_remain_to_update);
            }
            else if(rank_type.equals("AHP")){
                PON_remain_to_update = updateMapper.find_pon_to_update_AHP(Integer.parseInt(all_stations_and_count.get(i).get("num").toString()),all_stations_and_count.get(i).get("station").toString());
            }
            else if (rank_type.equals("TOPSIS")){
                PON_remain_to_update = updateMapper.find_pon_to_update_TOPSIS(Integer.parseInt(all_stations_and_count.get(i).get("num").toString()),all_stations_and_count.get(i).get("station").toString());
            }
            else {
                return null;
            }
            //step3.3找到该局站每个OLT有关的数据进行统计，得到每台OLT的名称、PON板数组、PON口数组
            List<Map<String, Object>> olt_state = cal_pon_board_and_port(OLT_name_list, all_stations_and_count.get(i).get("station").toString());
            //step3.4进行升级，结果加入result中。
            System.out.println("22222");
            update_pon_board_and_port(all_stations_and_count.get(i).get("station").toString(), PON_remain_to_update, olt_state);
            //todo:二次升级策略应该放在此处进行
            List<Map<String,Object>> PON_remain_to_update_erci =  erci_update(olt_state,PON_remain_to_update,rank_type,all_stations_and_count.get(i).get("station").toString());
            PON_remain_to_update.addAll(PON_remain_to_update_erci);
            list.add(PON_remain_to_update);
        }
        return list;
    }


    /**
     * 二次升级：根据更新的olt_state数组状态和每个PON_remain_to_update
     */
    public List<Map<String,Object>> erci_update(List<Map<String, Object>> olt_state,
                            List<Map<String,Object>> PON_remain_to_update,
                            String rank_type,String station){
        //1.统计当前局站的空闲10G端口数（找标号为2、3、4的PON板对应的数组下标）
        int free_10G_PON_num = 0;
        for(Map mp:olt_state){
            int[] board_temp = (int[]) mp.get("array_board");
            int[][] port_temp = (int[][]) mp.get("array_port");
            for(int i = 0; i  < board_temp.length;i++){
                if(board_temp[i] == 2 || board_temp[i] == 3 || board_temp[i] == 4){
                    for(int j = 0; j < port_temp[i].length; j++){
                        if(port_temp[i][j] == 0)
                            free_10G_PON_num++;
                    }
                }
            }
        }
        //2.找到当前局站内后free_10G_PON_num跳需要规划的数据
        int start_num = PON_remain_to_update.size();
        List<Map<String,Object>> PON_remain_to_update_erci = new ArrayList<>();
        if(rank_type.equals("zhijie")){
            PON_remain_to_update_erci = updateMapper.find_pon_to_update_zhijie_erci(start_num,free_10G_PON_num,station);
        }
        else if(rank_type.equals("AHP")){
            PON_remain_to_update_erci = updateMapper.find_pon_to_update_zhijie_AHP_erci(start_num,free_10G_PON_num,station);
        }
        else if (rank_type.equals("TOPSIS")){
            PON_remain_to_update_erci = updateMapper.find_pon_to_update_zhijie_TOPSIS_erci(start_num,free_10G_PON_num,station);
        }

        update_pon_board_and_port(station,PON_remain_to_update_erci,olt_state);
        for(Map mp:PON_remain_to_update_erci){
            mp.put("type","二次升级PON口");
        }
        return PON_remain_to_update_erci;
    }
}
